package com.ncepu.jjojcodesandbox.utils;

import com.ncepu.jjojcodesandbox.model.ExecuteMessage;
import org.springframework.util.StopWatch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author simon_jiang
 * @version 1.0
 */
public class ProcessUtils {

    private static final long TIME_OUT = 5000L;

    public static ExecuteMessage runProcessAndGetMessage(String compileCmd, String opName) throws InterruptedException, IOException {
        final ExecuteMessage executeMessage = new ExecuteMessage();

        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            Process compileProcess = Runtime.getRuntime().exec(compileCmd);
            Thread timeoutThread = new Thread(() -> {
                try {
                    Thread.sleep(TIME_OUT);
                    if (compileProcess.isAlive()) {
                        System.out.println("超时了，中断");
                        compileProcess.destroy();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            timeoutThread.setDaemon(true);
            timeoutThread.start();
            int exitValue = compileProcess.waitFor();
            executeMessage.setExitValue(exitValue);
            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(compileProcess.getInputStream()));
                 BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(compileProcess.getErrorStream()))) {
                if (exitValue == 0) {
                    System.out.println(opName + "成功");
                    StringBuilder compileOutputStringBuilder = new StringBuilder();
                    // 逐行读取
                    String compileOutputLine;
                    while ((compileOutputLine = bufferedReader.readLine()) != null) {
                        compileOutputStringBuilder.append(compileOutputLine);
                    }
                    executeMessage.setMessage(compileOutputStringBuilder.toString());
                } else {
                    // 异常退出
                    System.out.println(opName + "失败，错误码：" + exitValue);
                    // 分批获取进程的正常输出
                    StringBuilder compileOutputStringBuilder = new StringBuilder();
                    // 逐行读取
                    String compileOutputLine;
                    while ((compileOutputLine = bufferedReader.readLine()) != null) {
                        compileOutputStringBuilder.append(compileOutputLine);
                    }
                    executeMessage.setMessage(compileOutputStringBuilder.toString());

                    // 分批获取进程的错误输出
                    StringBuilder erorCompileOutputStringBuilder = new StringBuilder();
                    // 逐行读取
                    String errorCompileOutputLine;
                    while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
                        erorCompileOutputStringBuilder.append(errorCompileOutputLine);
                    }
                    executeMessage.setErrorMessage(erorCompileOutputStringBuilder.toString());
                }
                stopWatch.stop();
                executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return executeMessage;
    }
}
